package com.gitee.helioz.openai.common.util.http;

import com.gitee.helioz.openai.common.error.OpenAiRuntimeException;
import com.gitee.helioz.openai.common.util.json.GsonUtil;
import com.google.common.base.Stopwatch;
import com.google.gson.JsonObject;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 〈抽象实现HttpService〉
 *
 * @author <a href="https://gitee.com/helioz">Morning Starr</a>
 */
@Slf4j
public abstract class BaseHttpServiceImpl implements HttpService {

    @Getter
    @Setter
    private HttpProxyConfig httpProxyConfig = null;

    public BaseHttpServiceImpl() {
    }

    public BaseHttpServiceImpl(HttpProxyConfig httpProxyConfig) {
        this.httpProxyConfig = httpProxyConfig;
        // 代理参数检查
        if (Objects.nonNull(this.httpProxyConfig)) {
            this.httpProxyConfig.checkParam();
        }
    }

    /**
     * 初始化HTTP
     */
    protected abstract void initHttp();

    @Override
    public String get(String url) throws OpenAiRuntimeException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        String responseStr;
        try {
            responseStr = sendGetRequest(url);
        } catch (IOException ioe) {
            log.debug("发送请求发生IO异常，[GET]，URL=[{}], useTime={}, error={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS), ioe.getMessage(), ioe);
            stopwatch.stop();
            throw new OpenAiRuntimeException(ioe);
        }
        log.debug("发送请求耗时，[GET]，URL=[{}], useTime={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.stop();
        return responseStr;
    }

    @Override
    public String postFormData(String url, Map<String, Object> formMap, List<HttpFilePart> fileParts) throws OpenAiRuntimeException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        String responseStr;
        try {
            responseStr = sendPostFormData(url, formMap, fileParts);
        } catch (IOException ioe) {
            log.debug("发送请求发生IO异常，[MULTIPART]，URL=[{}], useTime={}, error={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS), ioe.getMessage(), ioe);
            stopwatch.stop();
            throw new OpenAiRuntimeException(ioe);
        }
        log.debug("发送请求耗时，[MULTIPART]，URL=[{}], useTime={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.stop();
        return responseStr;
    }

    @Override
    public String post(String url, String postData) throws OpenAiRuntimeException {
        log.debug("发送请求，[POST]，URL=[{}], body={}", url, postData);
        Stopwatch stopwatch = Stopwatch.createStarted();
        String responseStr;
        try {
            responseStr = sendPostJsonRequest(url, postData);
        } catch (IOException ioe) {
            log.debug("发送请求发生IO异常，[POST]，URL=[{}], useTime={}, error={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS), ioe.getMessage(), ioe);
            stopwatch.stop();
            throw new OpenAiRuntimeException(ioe);
        }
        log.debug("发送请求耗时，[POST]，URL=[{}], useTime={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.stop();
        return responseStr;
    }

    @Override
    public String post(String url, Object obj) throws OpenAiRuntimeException {
        // 处理请求参数
        return post(url, GsonUtil.toJson(obj));
    }

    @Override
    public String post(String url, JsonObject jsonObject) throws OpenAiRuntimeException {
        // 处理请求参数
        return post(url, jsonObject.toString());
    }

    @Override
    public String delete(String url) throws OpenAiRuntimeException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        String responseStr;
        try {
            responseStr = sendDeleteRequest(url);
        } catch (IOException ioe) {
            log.debug("发送请求发生IO异常，[DELETE]，URL=[{}], useTime={}, error={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS), ioe.getMessage(), ioe);
            stopwatch.stop();
            throw new OpenAiRuntimeException(ioe);
        }
        log.debug("发送请求耗时，[DELETE]，URL=[{}], useTime={}", url, stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.stop();
        return responseStr;
    }

    /**
     * 发送Get请求
     *
     * @param url 请求地址
     * @return 响应结果
     * @throws IOException IO异常
     */
    protected abstract String sendGetRequest(String url) throws IOException;

    /**
     * 发送Post Json RequestBody请求
     *
     * @param url      请求地址
     * @param jsonBody JSON格式请求内容
     * @return 响应结果
     * @throws IOException IO异常
     */
    protected abstract String sendPostJsonRequest(String url, String jsonBody) throws IOException;

    /**
     * 发送Post Form Data请求
     *
     * @param url       请求地址
     * @param formMap   表单数据
     * @param fileParts 文件集合
     * @return 响应结果
     * @throws IOException IO异常
     */
    protected abstract String sendPostFormData(String url, Map<String, Object> formMap, List<HttpFilePart> fileParts) throws IOException;

    /**
     * 发送Delete请求
     *
     * @param url 请求地址
     * @return 响应结果
     * @throws IOException IO异常
     */
    protected abstract String sendDeleteRequest(String url) throws IOException;

}
